#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""主动获取Promethus alertmanager告警消息

获取Promethus alertmanager告警消息信息记录并发送。
恢复消息暂时获取不到。

Attributes:
    __version__ (str): "0.0.1"
    __copyright__ (str): "Copyright (C) 2025 z"
    __license__ (str): "MIT"
    __author__ (str): "Z"
"""


import json
import requests

from wingman import db_enter, send, logger
from wingman.common.error import ErrorCode
from alertfingerprint import DEV_PA_FINGERPRINT, TEST_PA_FINGERPRINT, PRE_PA_FINGERPRINT, PROD_PA_FINGERPRINT
from config.system import PROMETHEUS_DEV_ADDR, PROMETHEUS_TEST_ADDR, PROMETHEUS_PRE_ADDR, PROMETHEUS_PROD_ADDR


class PAlertmanager():
    """
    官方地址：https://github.com/prometheus/alertmanager/blob/main/api/v2/openapi.yaml

    /status:获取Alertmanager实例及其集群的当前状态
    /receivers:获取所有接收者的列表(通知集成的名称)
    /alerts/groups:获取警报组列表
    /silence:新增、删除告警静默规则
    /alerts:查询、新增告警事件
    """

    def __validate_prometheus_data(self, item, env_name) -> dict:
        # 定义验证函数
        def get_valid_value(data, key, default=""):
            return data.get(key, default) if isinstance(data, dict) else default
        # 获取labels和annotations
        annotation_data = get_valid_value(item, "annotations", {})
        # receivers = get_valid_value(item, "receivers", {})
        status = get_valid_value(item, "status", {})
        label_data = get_valid_value(item, "labels", {})
        # 返回验证后的数据
        content = {
            "endsAt": get_valid_value(item, "endsAt"),
            "fingerprint": get_valid_value(item, "fingerprint"),
            "startsAt": get_valid_value(item, "startsAt"),
            "updatedAt": get_valid_value(item, "updatedAt"),
            # "name": get_valid_value(receivers, "name"),
            # "inhibitedBy": get_valid_value(status, "inhibitedBy"),
            # "silencedBy": get_valid_value(status, "silencedBy"),
            "state": get_valid_value(status, "state"),
            "alertname": get_valid_value(label_data, "alertname"),
            "prometheus": get_valid_value(label_data, "prometheus"),
            "severity": get_valid_value(label_data, "severity"),
            "hostname": get_valid_value(label_data, "hostname"),
            "instance": get_valid_value(label_data, "instance", "").replace(":9100", ""),
            "job": get_valid_value(label_data, "job"),
            "monitor": get_valid_value(label_data, "monitor"),
            "value": get_valid_value(annotation_data, "value"),
            "description": get_valid_value(annotation_data, "description"),
            "summary": get_valid_value(annotation_data, "summary"),
        }
        content.update(env_name)
        # logger.info(ErrorCode.SUCCESS.value, content, "alerts_get")
        return content

    def __update_system_file(self, new_fingerprint, pa_fingerprint):
        system_file_path = 'inspection/alertfingerprint.py'

        with open(system_file_path, 'r', encoding='utf-8') as file:
            lines = file.readlines()
        # 更新 PA_FINGERPRINT 的值
        for i, line in enumerate(lines):
            if line.startswith(pa_fingerprint):
                lines[i] = f'{pa_fingerprint} {new_fingerprint}\n'
                break

        # 写回文件
        with open(system_file_path, 'w', encoding='utf-8') as file:
            file.writelines(lines)

    def alerts_get(self, uri):
        """
        Returns:
            [
                {
                    "annotations": {
                        "description": "This is an alert meant to ensure that the entire alerting pipeline is functional.\nThis alert is always firing, therefore it should always be firing in Alertmanager\nand always fire against a receiver. There are integrations with various notification\nmechanisms that send a notification when this alert is not firing. For example the\n"DeadMansSnitch" integration in PagerDuty.\n",
                        "runbook_url": "https://runbooks.prometheus-operator.dev/runbooks/general/watchdog",
                        "summary": "An alert that should always be firing to certify that Alertmanager is working properly.",
                        "value": "1"
                    },
                    "endsAt": "2025-03-18T05:08:01.468Z",
                    "fingerprint": "e1749c6acab64267",
                    "receivers": [
                        {
                            "name": "Watchdog"
                        }
                    ],
                    "startsAt": "2025-01-03T01:10:31.468Z",
                    "status": {
                        "inhibitedBy": [],
                        "silencedBy": [],
                        "state": "active"
                    },
                    "updatedAt": "2025-03-18T05:04:01.470Z",
                    "generatorURL": "http://prometheus-k8s-0:9090/graph?g0.expr=vector%281%29&g0.tab=1",
                    "labels": {
                        "alertname": "Watchdog",
                        "prometheus": "monitoring/k8s",
                        "severity": "none"
                    }
                }
            ]
        """
        # 使用字典映射替代多个if语句
        ENV_CONFIG = {
            PROMETHEUS_DEV_ADDR: {
                "uri": uri,
                "env_name": {"customize_env": "dev_prometheus"},
                "fingerprint": DEV_PA_FINGERPRINT,
                "fingerprint_var": "DEV_PA_FINGERPRINT ="
            },
            PROMETHEUS_TEST_ADDR: {
                "uri": uri,
                "env_name": {"customize_env": "test_prometheus"},
                "fingerprint": TEST_PA_FINGERPRINT,
                "fingerprint_var": "TEST_PA_FINGERPRINT ="
            },
            PROMETHEUS_PRE_ADDR: {
                "uri": uri,
                "env_name": {"customize_env": "pre_prometheus"},
                "fingerprint": PRE_PA_FINGERPRINT,
                "fingerprint_var": "PRE_PA_FINGERPRINT ="
            },
            PROMETHEUS_PROD_ADDR: {
                "uri": uri,
                "env_name": {"customize_env": "prod_prometheus"},
                "fingerprint": PROD_PA_FINGERPRINT,
                "fingerprint_var": "PROD_PA_FINGERPRINT ="
            }
        }

        env_config = ENV_CONFIG.get(uri, {})
        if env_config["uri"] == "":
            # logger.critical(f"Unknown Prometheus URI: {uri}")
            return f"Unknown Prometheus URI: {uri}"

        url = f"{env_config["uri"]}/api/v2/alerts"
        response = requests.get(url)
        content = response.json()

        current_fingerprints = []
        new_fingerprints = []

        # 处理告警数据
        for alert in content:
            fingerprint = alert.get("fingerprint")
            if not fingerprint:
                continue

            new_fingerprints.append(fingerprint)
            if fingerprint not in env_config["fingerprint"]:
                current_fingerprints.append(fingerprint)
                result = self.__validate_prometheus_data(alert, env_config["env_name"])
                send(result, "alerts_get")
                db_enter(result, "alerts_get", "local")
                logger.info(ErrorCode.SUCCESS.value, result, "result")

        # 更新记录
        if new_fingerprints:
            self.__update_system_file(new_fingerprints, env_config["fingerprint_var"])

        return new_fingerprints

    # TODO 未测试部分
    def general_status(self, uri) -> dict:
        """
        Returns:
            {
            "cluster": {
                "name": "string",
                "status": "ready",
                "peers": [
                {
                    "name": "string",
                    "address": "string"
                }
                ]
            },
            "versionInfo": {
                "version": "string",
                "revision": "string",
                "branch": "string",
                "buildUser": "string",
                "buildDate": "string",
                "goVersion": "string"
            },
            "config": {
                "original": "string"
            },
            "uptime": "2019-08-24T14:15:22.123Z"
            }
        """
        url = f"{uri}/api/v2/status"
        response = requests.get(url)
        return response.json()

    def alertgroup(self, uri) -> list:
        """
        Returns:
            [
            {
                "labels": {
                "property1": "string",
                "property2": "string"
                },
                "receiver": {
                "name": "string"
                },
                "alerts": [
                {
                    "annotations": {
                    "property1": "string",
                    "property2": "string"
                    },
                    "receivers": [
                    {
                        "name": "string"
                    }
                    ],
                    "fingerprint": "string",
                    "startsAt": "2019-08-24T14:15:22.123Z",
                    "updatedAt": "2019-08-24T14:15:22.123Z",
                    "endsAt": "2019-08-24T14:15:22.123Z",
                    "status": {
                    "state": "unprocessed",
                    "silencedBy": [
                        "string"
                    ],
                    "inhibitedBy": [
                        "string"
                    ]
                    },
                    "labels": {
                    "property1": "string",
                    "property2": "string"
                    },
                    "generatorURL": "http://example.com"
                }
                ]
            }
            ]
        """
        url = f"{uri}/api/v2/alerts/groups"
        response = requests.get(url)
        return response.json()

    def receivers(self, uri) -> list:
        """

        Returns:
            [
                {
                    "name": "string"
                }
            ]
        """
        url = f"{uri}/api/v2/receivers"
        response = requests.get(url)
        return response.json()

    def silence_get(self, uri) -> list:
        """

        Returns:
            {
                "id": "string",
                "status": {
                "state": "expired"
                },
                "updatedAt": "2019-08-24T14:15:22.123Z",
                "matchers": [
                {
                    "name": "string",
                    "value": "string",
                    "isRegex": true,
                    "isEqual": true
                }
                ],
                "startsAt": "2019-08-24T14:15:22.123Z",
                "endsAt": "2019-08-24T14:15:22.123Z",
                "createdBy": "string",
                "comment": "string"
            }
        """
        url = f"{uri}/api/v2/silences"
        response = requests.get(url)
        return response.json()

    def silence(self, uri) -> dict:
        """
        Args:
            id string 可选
            matchers array[object (matcher) {4}]  matchers 必需
                >= 1 items
                    name string  必需
                    value string  必需
                    isRegex boolean  必需
                    isEqual boolean  可选
                    默认值: true
            startsAt string <date-time> 必需
            endsAt string <date-time> 必需
            createdBy string  必需
            comment string  必需

        Returns:
            {
            "silenceID": "string"
            }
        """
        url = f"{uri}/api/v2/silences"
        payload = json.dumps({
                                "id": "1",
                                "matchers": [
                                    {
                                        "team": "elk"
                                    }
                                ],
                                "startsAt": "2023-07-07T07:07:00Z",
                                "endsAt": "2023-08-08T08:08:00Z",
                                "createdBy": "cuiliang",
                                "comment": "test API"
                            })
        headers = {'Content-Type': 'application/json'}
        response = requests.post(url, payload, headers)
        return response.json()

    def general_silence_del_get(self, uri, silenceID) -> dict:
        """
        Returns:
            {}
        """
        url = f"{uri}/api/v2/silences{silenceID}"
        payload = ""
        headers = {}
        response = requests.get(url, payload, headers)
        return response.json()

    def general_silence_del(silenceID) -> dict:
        """
        Args:
            silenceID string  必需
        Raises:
            ID of the silence to get
        Returns:
            {}
        """
        url = f"{uri}/api/v2/silences{silenceID}"
        response = requests.delete(url)
        return response.json()

    def alerts(self, uri):
        """
        xx
        Args:
            startsAt string <date-time> 可选
            endsAt string <date-time> 可选
            annotations object  labelSet 可选
            labels object labelSet 必需
            generatorURL string <uri> 可选

        Returns:
            {}
        """
        url = f"{uri}/api/v2/alerts"
        payload = json.dumps([
                                {
                                    "startsAt": "2019-08-24T14:15:22.123Z",
                                    "endsAt": "2019-08-24T14:15:22.123Z",
                                    "annotations": {
                                        "property1": "string",
                                        "property2": "string"
                                    },
                                    "labels": {
                                        "alertname": "Watchdog",
                                        "prometheus": "monitoring/k8s",
                                        "severity": "none"
                                    },
                                    "generatorURL": "http://example.com"
                                }
                            ])
        headers = {'Content-Type': 'application/json'}
        response = requests.post(url, payload, headers)
        return response.json()


if __name__ in "__main__":

    pam = PAlertmanager()
    print(pam.alerts_get(PROMETHEUS_DEV_ADDR))
    print(pam.alerts_get(PROMETHEUS_TEST_ADDR))
    print(pam.alerts_get(PROMETHEUS_PRE_ADDR))
    print(pam.alerts_get(PROMETHEUS_PROD_ADDR))
